fix(chat): thread UI-selected model into the chat workflow#638
fix(chat): thread UI-selected model into the chat workflow#638arpitgupta1214 wants to merge 3 commits into
Conversation
The chat UI sends the selected model in the POST /api/chat/workflow body, but the schema stripped it and the handler only read the chat's persisted model_id (null for new chats) — so every request billed the default model. Accept `model` in the schema and prefer validated.model ?? chat.model_id ?? DEFAULT_MODEL_ID. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
More reviews will be available in 3 minutes and 22 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (2)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
1 issue found across 4 files
Confidence score: 4/5
- This PR is likely safe to merge with minimal risk because the reported issue is moderate severity (5/10) and scoped to model-selection fallback behavior rather than a broad workflow break.
- In
lib/chat/handleChatWorkflowStream.ts, whitespace-onlymodeloverrides are currently treated as valid, which can skip persisted/default fallback and lead to unexpected model choice for affected requests. - The issue appears concrete (confidence 8/10) but localized, so impact should be limited to inputs where
modelis blank/whitespace rather than all chat flows. - Pay close attention to
lib/chat/handleChatWorkflowStream.ts- ensuremodelvalues are trimmed/validated so fallback logic still applies for empty overrides.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="lib/chat/handleChatWorkflowStream.ts">
<violation number="1" location="lib/chat/handleChatWorkflowStream.ts:97">
P2: Whitespace-only `model` values are treated as valid overrides, bypassing fallback to persisted/default model.</violation>
</file>
Architecture diagram
sequenceDiagram
participant UI as Chat UI
participant API as API Route (POST /api/chat/workflow)
participant Val as validateChatWorkflow
participant Handler as handleChatWorkflowStream
participant DB as Database
participant Workflow as Chat Workflow
Note over UI,Workflow: Chat Model Selection Flow
UI->>API: POST with body { messages, model: "openai/gpt-5.4-mini" }
API->>Val: validateChatWorkflow(request)
Val->>Val: Parse body with chatWorkflowBodySchema
Note over Val: Zod schema now accepts optional model field
alt Valid body with model
Val-->>API: { model: "openai/gpt-5.4-mini", ... }
else Valid body without model
Val-->>API: { model: undefined, ... }
end
API->>Handler: handleChatWorkflowStream(request)
Handler->>DB: selectChats(chatId)
DB-->>Handler: { model_id: "anthropic/claude-opus-4.6" } (or null)
alt validated.model is provided
Note over Handler: Use UI-selected model
Handler->>Handler: modelId = "openai/gpt-5.4-mini"
else validated.model is undefined AND chat.model_id exists
Note over Handler: Use persisted chat model
Handler->>Handler: modelId = "anthropic/claude-opus-4.6"
else neither model source is available
Note over Handler: Fall back to default
Handler->>Handler: modelId = DEFAULT_MODEL_ID
end
Handler->>Workflow: start workflow with { modelId }
Workflow-->>Handler: Stream response
Handler-->>UI: Streaming response with correct model billing
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| // persisted model_id, then the default. Without this the workflow | ||
| // always billed DEFAULT_MODEL_ID since model_id is null until a | ||
| // chat is explicitly PATCHed. | ||
| const modelId = validated.model ?? chat.model_id ?? DEFAULT_MODEL_ID; |
There was a problem hiding this comment.
P2: Whitespace-only model values are treated as valid overrides, bypassing fallback to persisted/default model.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/chat/handleChatWorkflowStream.ts, line 97:
<comment>Whitespace-only `model` values are treated as valid overrides, bypassing fallback to persisted/default model.</comment>
<file context>
@@ -90,7 +90,11 @@ export async function handleChatWorkflowStream(request: NextRequest): Promise<Re
+ // persisted model_id, then the default. Without this the workflow
+ // always billed DEFAULT_MODEL_ID since model_id is null until a
+ // chat is explicitly PATCHed.
+ const modelId = validated.model ?? chat.model_id ?? DEFAULT_MODEL_ID;
const recoupOrgId = session.clone_url
? (extractOrgId(session.clone_url) ?? undefined)
</file context>
| const modelId = validated.model ?? chat.model_id ?? DEFAULT_MODEL_ID; | |
| const requestedModelId = validated.model?.trim(); | |
| const modelId = requestedModelId ? requestedModelId : chat.model_id ?? DEFAULT_MODEL_ID; |
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
E2E verification (live, against this PR's preview)Drove the test chat UI (
The only variable is the backend: unfixed → billed the hardcoded default; fixed → billed the user's choice. Confirmed two independent ways for turn 2:
|
There was a problem hiding this comment.
0 issues found across 4 files (changes from recent commits).
Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.
Re-trigger cubic
|
Closing — after checking the open-agents reference, threading How open-agents resolves the model: server-side, from the persisted
Our handler already matches this: The actual fix (open-agents-faithful), no request-body change:
Tracked on recoupable/chat#1767. Thanks @arpitgupta1214 — good prompt to go verify against the reference. |
Model selection from the chat UI was ignored by the workflow path — every request billed the default model.
The UI already sends the selected
modelin thePOST /api/chat/workflowbody, butchatWorkflowBodySchemahad nomodelfield (Zod stripped it) and the handler only read the chat's persistedmodel_id(null until a chat is PATCHed). Now the schema acceptsmodeland the handler usesvalidated.model ?? chat.model_id ?? DEFAULT_MODEL_ID.Test plan
pnpm test lib/chat/__tests__/validateChatWorkflow.test.ts lib/chat/__tests__/handleChatWorkflowStream.test.ts— added cases for acceptingmodel, omitting it, and preferring it over a persistedmodel_id.🤖 Generated with Claude Code
Summary by cubic
Honor the UI-selected model in the chat workflow so requests use the chosen model instead of the default. The request schema now accepts
model, and the handler prefers it overchat.model_idand the default.Bug Fixes
modeltochatWorkflowBodySchema.handleChatWorkflowStream, usevalidated.model ?? chat.model_id ?? DEFAULT_MODEL_ID.model_id.Refactors
Written for commit d5e63a0. Summary will update on new commits.